package com.example.observer.dubbo;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import java.util.stream.Collectors;

public class ReflectUtils {


    public static Set<ParameterizedType> findParameterizedTypes(Class<?> sourceClass) {
        // add generic interfaces
        List<Type> genericTypes = new ArrayList<>(Arrays.asList(sourceClass.getGenericInterfaces()));
        // add generic super class
        genericTypes.add(sourceClass.getGenericSuperclass());


        // find ParameterizedType
        Set<ParameterizedType> parameterizedTypeSet = genericTypes.stream()
                .filter(t -> t instanceof ParameterizedType) // find parameterized type
                .map(t -> ParameterizedType.class.cast(t))
                .collect(Collectors.toSet());
        if (parameterizedTypeSet.isEmpty()) {
            // find super types recursively
            genericTypes.stream()
                    .filter(t -> t instanceof Class)
                    .map(t -> Class.class.cast(t))
                    .forEach( superClass -> parameterizedTypeSet.addAll(findParameterizedTypes(superClass)));
        }
        return Collections.unmodifiableSet(parameterizedTypeSet);
    }

}
